/*-------------------------------------------------------------------------
 *
 * username.c
 *	  获取用户名
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/common/username.c
 *
 *-------------------------------------------------------------------------
 */

#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif

#include <pwd.h>
#include <unistd.h>

#include "common/username.h"

/*
 * 返回当前用户名称，存在静态缓冲区中
 * 出错时返回 NULL，并将 *errstr 设置为指向 palloc' 的消息
 */
const char * get_user_name(char **fc_errstr)
{
#ifndef WIN32
	struct passwd *fc_pw;
	uid_t		fc_user_id = geteuid();

	*fc_errstr = NULL;

	errno = 0;					/* 在调用之前清除 errno */
	fc_pw = getpwuid(fc_user_id);
	if (!fc_pw)
	{
		*fc_errstr = psprintf(_("could not look up effective user ID %ld: %s"),
						   (long) fc_user_id,
						   errno ? strerror(errno) : _("user does not exist"));
		return NULL;
	}

	return fc_pw->pw_name;
#else
	/* Microsoft 推荐的缓冲区大小为 UNLEN+1，其中 UNLEN = 256 */
	/* “静态”变量在函数退出后仍然存在 */
	static char username[256 + 1];
	DWORD		len = sizeof(username);

	*errstr = NULL;

	if (!GetUserName(username, &len))
	{
		*errstr = psprintf(_("user name lookup failure: error code %lu"),
						   GetLastError());
		return NULL;
	}

	return username;
#endif
}


/*
 * 返回当前用户名称，存在静态缓冲区中或退出
 */
const char * get_user_name_or_exit(const char *fc_progname)
{
	const char *fc_user_name;
	char	   *fc_errstr;

	fc_user_name = get_user_name(&fc_errstr);

	if (!fc_user_name)
	{
		fprintf(stderr, "%s: %s\n", fc_progname, fc_errstr);
		exit(1);
	}
	return fc_user_name;
}
